package com.xueshandai.db.migration.persistence.implement;

import com.xueshandai.db.migration.mode.ColumnData;
import com.xueshandai.db.migration.mode.LineData;
import com.xueshandai.db.migration.mode.MetaData;
import com.xueshandai.db.migration.persistence.Access;

import java.sql.*;
import java.util.LinkedList;
import java.util.List;

/**
 * Created by Zetas on 2014/12/25.
 */
public class AccessMSSQLImpl implements Access {

    private String tableName;
    private Connection connection;
    private PreparedStatement preparedStatement;
    private ResultSetMetaData resultSetMetaData;
    private ResultSet resultSet;
    private List<MetaData> metaDataList;

    public AccessMSSQLImpl(Connection connection, String tableName) {
        this.connection = connection;
        this.metaDataList = new LinkedList<MetaData>();
        this.tableName = tableName;
        try {
            this.preparedStatement = connection.prepareStatement("select * from "+tableName);
            resultSet = preparedStatement.executeQuery();
            resultSetMetaData = resultSet.getMetaData();
            int columnCount = resultSetMetaData.getColumnCount();
            for (int i=1; i<=columnCount; i++) {
                MetaData metaData = new MetaData();
                metaData.setColumnClassName(resultSetMetaData.getColumnClassName(i));
                metaData.setColumnTypeName(resultSetMetaData.getColumnTypeName(i));
                metaData.setColumnName(resultSetMetaData.getColumnName(i));
                metaData.setColumnDisplaySize(resultSetMetaData.getColumnDisplaySize(i));
                metaDataList.add(metaData);
            }
        } catch (SQLException e) {
            logger.error(e);
        }
    }

    @Override
    public boolean next() {
        boolean result = false;
        try {
            result = resultSet.next();
        } catch (SQLException e) {
            logger.error(e);
        }

        return result;
    }

    @Override
    public LineData readLine() {
        LineData lineData = new LineData();
        try {
            for (MetaData metaData : metaDataList) {
                String data = resultSet.getString(metaData.getColumnName());
                ColumnData columnData = new ColumnData();
                columnData.setMetaData(metaData);
                columnData.setData(data);
                lineData.add(columnData);
            }
        } catch (SQLException e) {
            logger.error(e);
        }
        return lineData;
    }

    @Override
    public void writeLine(LineData lineData) {
        StringBuffer columnNames = new StringBuffer();
        StringBuffer columnValues = new StringBuffer();
        int i = 1;
        for (ColumnData columnData : lineData.getColumnDataList()) {
            if ( i < lineData.getColumnDataList().size() ) {
                columnNames.append(columnData.getMetaData().getColumnName()+",");
                columnValues.append("'"+columnData.getData()+"'"+',');
            } else {
                columnNames.append(columnData.getMetaData().getColumnName());
                columnValues.append("'"+columnData.getData()+"'");
            }

        }
        String sqlStr = "insert into "+tableName+" ("+columnNames.toString()+") value ("+columnValues.toString()+")";

        try {
            int count = preparedStatement.executeUpdate(sqlStr);
            logger.info(tableName+"表成功插入"+count+"条数据");
        } catch (SQLException e) {
            logger.error(e);
        }
    }

    @Override
    public void destroy() {
        if ( resultSet != null ) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                logger.error(e);
            }
        }
        if ( preparedStatement != null ) {
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                logger.error(e);
            }
        }
        if ( connection != null ) {
            try {
                connection.close();
            } catch (SQLException e) {
                logger.error(e);
            }
        }
    }
}
